package com.stmt.analytic.graph.algorithm.dc;


import com.stmt.analytic.graph.algorithm.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;

public class DegreeCentrality {

    private Direction direction;
    private DegreeCentralityResults results;
    private MemoryBasedGraph graph;
    private TimerWatcher clock;

    public static DegreeCentralityBuilder newBuilder() {
        return new DegreeCentralityBuilder();
    }


    public DegreeCentralityResults compute() {
        //final Logger logger = LoggerFactory.getLogger(DegreeCentrality.class);
        clock = new TimerWatcher();
        clock.startClock();
        results = new DegreeCentralityResults();
        int nodeCount = graph.nodeCount();
        AdjacencyMatrix adjacencyMatrix = graph.getAdjacencyMatrix();
        for (int i = 0; i < nodeCount; i++) {
            int degree = adjacencyMatrix.armBothSize(i);
            results.set(graph.toOriginalId(i), (double) degree);
        }
        clock.endClock();
        clock.report();
        return results;
    }

    public static class DegreeCentralityBuilder {

        private DegreeCentrality task;

        private Collection<String> vertices;

        private Collection<Pair<String, String>> edges;

        private DegreeCentralityBuilder() {
            task = new DegreeCentrality();
        }

        public DegreeCentralityBuilder withDefaultDirection() {
            task.direction = Direction.BOTH;
            return this;
        }

        public DegreeCentralityBuilder withVertices(Collection<String> inputVertices) {
            this.vertices = inputVertices;
            return this;
        }

        public DegreeCentralityBuilder withEdges(Collection<Pair<String, String>> inputEdges) {
            this.edges = inputEdges;
            return this;
        }

        public DegreeCentrality build() {
            // 1. 构造MemoryBasedGraph
            Objects.requireNonNull(vertices, "Vertices collection is null.");
            Objects.requireNonNull(edges, "Edges collection is null.");
            this.task.graph = MemoryBasedGraph.from(vertices, edges);
            return task;
        }

    }

    public static void main(String[] args) {
        Collection<String> vertices = new ArrayList<>();
        Collection<Pair<String, String>> edges = new ArrayList<>();
        vertices.add("a");
        vertices.add("b");
        vertices.add("c");
        vertices.add("d");
        vertices.add("e");

        edges.add(new Pair<>("a", "b"));
        edges.add(new Pair<>("c", "b"));
        edges.add(new Pair<>("d", "b"));
        edges.add(new Pair<>("e", "b"));
        edges.add(new Pair<>("e", "a"));
        edges.add(new Pair<>("e", "c"));

        DegreeCentrality degreeCentrality = DegreeCentrality.newBuilder()
                .withDefaultDirection()
                .withVertices(vertices)
                .withEdges(edges)
                .build();
        DegreeCentralityResults results = degreeCentrality.compute();
        Collection<DegreeCentralityResults.DegreeCentralityResult> unWrapped = results.unwrap();
        unWrapped.forEach(dc -> {
            System.out.println(dc);
        });

    }
}
